#include "WaterSystem.h"
#include "GameSceneManager.h"

Ogre::String mSkyBoxes[_def_SkyBoxNum] = {
	                         "Sky/ClubTropicana",
                             "Sky/Stormy",
                             "Sky/EarlyMorning",
                             "Sky/Evening",
                             "Sky/Clouds"};

Ogre::Vector3 mSunPosition[_def_SkyBoxNum] = {
	                             Ogre::Vector3(0,10000,-90000),
                                 Ogre::Vector3(0,10000,-90000)/2.5,
                                 Ogre::Vector3(13000,0,120000)/3,
                                 Ogre::Vector3(-50000,-5000,50000),
								 Ogre::Vector3(0,0,0)};

Ogre::Vector3 mSunColor[_def_SkyBoxNum] = {
	                          Ogre::Vector3(1, 0.9, 0.6)/5,
                              Ogre::Vector3(0.75, 0.65, 0.45)/2,
                              Ogre::Vector3(1,0.6,0.4),
                              Ogre::Vector3(1,0.4,0.1),
							  Ogre::Vector3(0,0,0)};

Hydrax::Module::ProjectedGrid::Options mPGOptions[_def_SkyBoxNum] = {
	                          Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity),
	                          Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity, 45.5f, 7.0f, false),
	                          Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity, 32.5f, 7.0f, false),
	                          Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity, 32.5f, 7.0f, false),
	                          Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity, 20.0f, 7.0f, false)};

Hydrax::Noise::Perlin::Options mPerlinOptions[_def_SkyBoxNum] = {
							  Hydrax::Noise::Perlin::Options(8, 0.085f, 0.49f, 1.4f, 1.27),
							  Hydrax::Noise::Perlin::Options(8, 0.085f, 0.49f, 1.4f, 1.27),
							  Hydrax::Noise::Perlin::Options(8, 0.085f, 0.49f, 1.4f, 1.27),
							  Hydrax::Noise::Perlin::Options(8, 0.075f, 0.49f, 1.4f, 1.27),
							  Hydrax::Noise::Perlin::Options(8, 0.085f, 0.49f, 1.4f, 1.27)};


WaterSystem::WaterSystem() {
	setup();
}

WaterSystem::~WaterSystem() {

}

void WaterSystem::setup() {
	// Create Hydrax object
	GameSceneManager::getSingleton()->getCamera()->setFarClipDistance(99999*6);

	mHydrax = new Hydrax::Hydrax(GameSceneManager::getSingleton()->getSceneManager()
								,GameSceneManager::getSingleton()->getCamera()
								);

	

	// Set RTT textures quality
	mHydrax->setRttOptions(
			   Hydrax::RttOptions(// Reflection tex quality
								  Hydrax::TEX_QUA_1024,
								  // Refraction tex quality
								  Hydrax::TEX_QUA_1024,
								  // Depth tex quality
								  Hydrax::TEX_QUA_1024));

	//Hydrax::MeshOptions mo = Hydrax::MeshOptions(Hydrax::Size(1500,1500),128); 

	//mHydrax->getMesh()->setOptions(&Hydrax::MeshOptions(Hydrax::Size(1500,1500),128));
	//mHydrax->seto

	// Set components
	mHydrax->setComponents(
		static_cast<Hydrax::HydraxComponent>(Hydrax::HYDRAX_COMPONENT_SUN    |
											 Hydrax::HYDRAX_COMPONENT_FOAM   |
											 Hydrax::HYDRAX_COMPONENT_DEPTH  |
											 Hydrax::HYDRAX_COMPONENT_SMOOTH |
											 Hydrax::HYDRAX_COMPONENT_CAUSTICS));


	// Create our projected grid module  
	Hydrax::Module::ProjectedGrid *mModule 
		= new Hydrax::Module::ProjectedGrid(// Hydrax parent pointer
											mHydrax,
											// Noise module
											new Hydrax::Noise::Perlin(/* Default options (8, 0.085f, 0.49f, 1.4f, 1.27f) */),
											// Base plane
											Ogre::Plane(Ogre::Vector3(0,1,0), Ogre::Vector3(0,0,0)),
											//Ogre::Plane(Ogre::Vector3(100,1,100), Ogre::Vector3(100,0,100)),
											// Projected grid options (Can be updated each frame -> setOptions(...))
											Hydrax::Module::ProjectedGrid::Options(_def_PGComplexity),0); ///* See more constructors */

	
	//mModule->setOptions(

	// Set our module
	mHydrax->setModule(static_cast<Hydrax::Module::Module*>(mModule));

	// Set our shader mode
	mHydrax->setShaderMode(Hydrax::MaterialManager::SM_HLSL); //SM_CG

	// Create water
	mHydrax->create();

	// Adjust some options
	mHydrax->setPosition(Ogre::Vector3(570,180,970));
	mHydrax->setPlanesError(37.5);
	mHydrax->setDepthLimit(110);
	mHydrax->setSunPosition(mSunPosition[0]);
	mHydrax->setSunColor(mSunColor[0]);
	mHydrax->setNormalDistortion(0.025);
	mHydrax->setDepthColor(Ogre::Vector3(0.04,0.135,0.185));
	mHydrax->setSmoothPower(5);
	mHydrax->setCausticsScale(12);
	mHydrax->setGlobalTransparency(0.1);
	mHydrax->setFullReflectionDistance(99999997952.0);
	mHydrax->setGlobalTransparency(0);
	mHydrax->setPolygonMode(0);

	//Hydrax::Mesh::Options mMeshOptions = Hydrax::Mesh::Options(128,Hydrax::Size(1000000,1000000),Hydrax::Mesh::VertexType::VT_POS_NORM_UV);
	//Hydrax::Mesh *mesh = mHydrax->getMesh();
	//mHydrax->getMesh()->setOptions(mMeshOptions);

	//mesh->setOptions(mMeshOptions);
		int mCurrentSkyBox = 0;

		GameSceneManager::getSingleton()->getSceneManager()->setSkyBox(true, mSkyBoxes[mCurrentSkyBox], 99999*3, true);
        
		mHydrax->setSunPosition(mSunPosition[mCurrentSkyBox]);
        mHydrax->setSunColor(mSunColor[mCurrentSkyBox]);

        // Update light 0 light position and colour
        //mSceneMgr->getLight("Light0")->setPosition(mSunPosition[mCurrentSkyBox]);
        //mSceneMgr->getLight("Light0")->setSpecularColour(mSunColor[mCurrentSkyBox].x,mSunColor[mCurrentSkyBox].y,mSunColor[mCurrentSkyBox].z);

		// Update perlin noise options
		static_cast<Hydrax::Noise::Perlin*>(mHydrax->getModule()->getNoise())
			->setOptions(mPerlinOptions[mCurrentSkyBox]);

		// Update projected grid options
		static_cast<Hydrax::Module::ProjectedGrid*>(mHydrax->getModule())
			->setOptions(mPGOptions[mCurrentSkyBox]);

}

bool WaterSystem::update(Real time) {
	mHydrax->update(time);

	return true;
}